<template>
	<view class="forum-detail" @touchmove="touchMove" @touchend="touchEnd">
		<view class="top-box">
			<view class="user">
				<image class="avatar" :src="content.avatar" mode="aspectFill"></image>
				<view class="name u-line-1">{{ content.name }}</view>
			</view>
			<view class="content">
				<view class="name u-line-1">{{ content.type_name }}</view>
				<view class="text" v-if="content.content">{{ content.content }}</view>
				<view class="audio" v-if="content.voice" @click="playVoice(content.id, content.voice)">
					<view class="wifi-cont" :class="{ 'animation': playVoiceId === content.id && isAudioPlay }">
						<view class="wifi-circle first"></view>
						<view class="wifi-circle second"></view>
						<view class="wifi-circle third"></view>
					</view>
					<text class="duration">{{ content.voice_time }}"</text>
				</view>
				<view class="bottom">
					<view class="time">{{ content.create_time }}</view>
					<!-- <image class="icon" src="@/static/icons/comment.png" mode="aspectFill"></image> -->
				</view>
			</view>
		</view>

		<view class="comment-card">
			<view class="item" v-for="(item, index) in replyList" :key="index">
				<view class="content">
					<view class="user">
						<image class="avatar" :src="item.avatar" mode="aspectFill"></image>
						<view class="name u-line-1">{{ item.name }}</view>
					</view>
					<view class="info">
						<view class="comment-text" v-if="item.content">{{ item.content }}</view>
						<view class="audio" v-if="item.voice" @click="playVoice(item.id, item.voice)">
							<view class="wifi-cont" :class="{ 'animation': playVoiceId === item.id && isAudioPlay }">
								<view class="wifi-circle first"></view>
								<view class="wifi-circle second"></view>
								<view class="wifi-circle third"></view>
							</view>
							<text class="duration">{{ item.voice_time }}"</text>
						</view>
						<view class="bottom">
							<view class="time">{{ item.create_time }}</view>
							<view class="delete" @click="deleteComment(item.id)" v-if="item.is_myself == 1">
								<u-icon name="trash-fill" color="#9e2024" size="28rpx"></u-icon>
							</view>
						</view>
					</view>
				</view>
			</view>
		</view>

		<view class="bottom-box">
			<view class="emoji" @click="voiceShow = !voiceShow">
				<image v-if="voiceShow" class="icon" src="@/static/icons/jianpan.png" mode="aspectFill"></image>
				<image v-else class="icon" src="@/static/icons/yuyin.png" mode="aspectFill"></image>
			</view>
			<view class="voice" v-if="voiceShow" @touchstart="touchStart">{{ $t('按住说话') }}</view>
			<view class="input-box" v-else>
				<input type="text" class="input" v-model="chat_content" :placeholder="$t('请输入')" cursor-spacing="5"
					confirm-type="send" @confirm="formSubmit" />
				<view class="send" @click="formSubmit">
					<image class="icon" src="@/static/icons/send.png" mode="aspectFill"></image>
				</view>
			</view>
		</view>

		<view class="voice-mask" v-if="voiceState !== 0">
			<view class="voice-enter" v-if="voiceState === 1">
				<view class="flex">
					<image class="icon" src="@/static/icons/luyin.png" mode="aspectFill"></image>
					<view class="volume">
						<view class="volume-3"></view>
						<view class="volume-2"></view>
						<view class="volume-1"></view>
					</view>
				</view>
				<view class="text">{{ $t('向上滑动取消') }}</view>
			</view>
			<view class="voice-cancel" v-else>
				<image class="icon" src="@/static/icons/quxiaofabu.png" mode="aspectFill"></image>
				<view class="text">{{ $t('取消') }}</view>
			</view>
		</view>
	</view>
</template>

<script>
	import $config from '@/api/http.baseUrl.js'
	export default {
		data() {
			return {
				content: {},

				voiceShow: false,

				/* 播放声音 */
				audioContext: null,
				isAudioPlay: false,
				playVoiceId: '',

				/* 评论文本 */
				chat_content: '',

				/* 录音 */
				rec: null,
				voiceState: 0, // 语音输入状态 （0-未点击语音；1-输入中；2-取消）
				voiceCancelState: false, // 语音取消状态
				startLocation: 0, // 记录滑动初始点击，在页面上的位置
				locationY: 0, // 手指上下滑动的距离
				forum_id: 0,
				params: {
					forum_id: 0,
					page: 1,
					page_size: 10,
				},
				last_page: '',
				replyList: [],
				status: 'loadmore',
				voice_time: 0,
				voice: '',

			}
		},

		onLoad(options) {
			this.params.forum_id = options.forum_id
			this.getForumDetail();
			this.getForumReply();
		},
		onReachBottom() {
			if (this.last_page > this.params.page) {
				this.status = 'loading'
				this.params.page++
				this.getForumReply()
			} else {
				this.status = 'nomore'
			}
		},
		methods: {
			getForumDetail() {
				this.$u.api.forum_info({
					id: this.params.forum_id
				}).then(res => {
					this.content = res.data.data
				});
			},
			getForumReply() {
				this.status = 'loading'
				this.$u.api.forum_reply(this.params).then(res => {
					this.last_page = res.data.total_page
					this.replyList = [...this.replyList, ...res.data.data];
				});
			},
			/* 播放声音 */
			createAudio() {
				this.audioContext = uni.createInnerAudioContext()
				this.audioContext.autoplay = true

				this.audioContext.onPlay(() => {
					this.isAudioPlay = true
				})
				this.audioContext.onStop(() => {
					this.isAudioPlay = false
				})
				this.audioContext.onEnded(() => {
					this.isAudioPlay = false
					this.playVoiceId = ''
				})
				this.audioContext.onError((err) => {
					uni.showToast({
						title: '播放失败',
						icon: 'error'
					})

					this.isAudioPlay = false
					this.playVoiceId = ''
				})
			},
			playVoice(id, url) {
				if (this.audioContext) {
					this.audioContext.stop()
					this.audioContext.destroy()
					this.audioContext = null
				}

				if (id === this.playVoiceId) {
					this.playVoiceId = ''
					return
				}

				this.createAudio()
				this.audioContext.src = url
				this.audioContext.play()
				this.playVoiceId = id
			},
			clearVoice() {
				this.isAudioPlay = false
				this.playVoiceId = ''

				if (this.audioContext) {
					this.audioContext.stop()
					this.audioContext.destroy()

					/* 取消监听音频事件 */
					this.audioContext.offPlay()
					this.audioContext.offPause()
					this.audioContext.offEnded()
					this.audioContext.offError()

					this.audioContext = null
				}
			},

			/* 录音 */
			// 手指触碰到元素触发
			touchStart(e) {
				this.voiceState = 1
				this.voiceCancelState = false

				// 相对于父元素的距离
				this.startLocation = e.changedTouches[0].pageY

				// 开始录音
				this.rec = uni.getRecorderManager()
				this.rec.start({
					duration: 500000,
					sampleRate: 16000,
					format: 'mp3'
				})

				// 录音停止事件
				this.rec.onStop((res) => {
					if (this.voiceCancelState) return

					let tempFilePath = res.tempFilePath
					console.log(tempFilePath) // 录音文件的临时路径
					this.voice = tempFilePath
					this.audioData = [{
						title: '录音',
						fileUrl: tempFilePath
					}]
					const innerAudioContext = uni.createInnerAudioContext()
					innerAudioContext.src = tempFilePath
					innerAudioContext.onCanplay(() => {
						this.voice_time = innerAudioContext.duration
					})
					this.submitBefore()
				})
				// 录音错误事件
				this.rec.onError((errMsg) => {
					console.log('录音错误事件', errMsg)
				})
			},
			submitBefore() {
				var that = this;
				// 先把录音文件上传上去
				if (this.voice) {
					uni.uploadFile({
						url: `${$config.baseUrl}/system/basic/postUploadOne`,
						filePath: this.voice,
						name: 'img',
						formData: {
							'type': 'file'
						},
						success: (uploadFileRes) => {
							let file = JSON.parse(uploadFileRes.data);
							that.voice = file.path
							that.submit();
						}
					});
				} else {
					return false;
				}
			},
			submit() {
				this.$u.api.forum_reply_action({
					forum_id: this.params.forum_id,
					voice: this.voice,
					voice_time: this.voice_time,
				}).then(res => {
					this.$u.toast(res.msg)
					this.voice = '';
					this.voice_time = 0;
					setTimeout(() => {
						this.params.page = 1
						this.replyList = []
						this.status = 'loadmore'
						this.getForumReply();
					}, 500)
				});
			},
			// 手指滑动事件
			touchMove(e) {
				if (this.voiceState === 0) return

				let y = e.changedTouches[0].pageY - this.startLocation
				if (this.voiceState === 1 && y < -120) {
					this.voiceState = 2
					this.voiceCancelState = true
					// 暂停录音
					this.rec.pause()
				}
				if (this.voiceState === 2 && y > -120) {
					this.voiceState = 1
					this.voiceCancelState = false
					// 继续录音
					this.rec.resume()
				}

				this.locationY = y
			},
			// 手指松开事件
			touchEnd(e) {
				if (this.voiceState === 0) return

				this.voiceState = 0

				// 停止录音
				this.rec.stop()
			},
			/* 文字评论 */
			formSubmit() {
				this.$u.api.forum_reply_action({
					forum_id: this.params.forum_id,
					content: this.chat_content,
				}).then(res => {
					this.$u.toast(res.msg)
					this.chat_content = '';
					setTimeout(() => {
						this.params.page = 1
						this.replyList = []
						this.status = 'loadmore'
						this.getForumReply();
					}, 500)
				});
			},
			deleteComment(reply_id) {
				uni.showModal({
					title: this.$t('确认删除'),
					success: (res) => {
						if (res.confirm) {
							this.$u.api.delete_reply({
								reply_id: reply_id
							}).then(res1 => {
								this.$u.toast(res1.msg)
								setTimeout(() => {
									this.params.page = 1
									this.replyList = []
									this.status = 'loadmore'
									this.getForumReply();
								}, 500)
							});
						}
					}
				})
			}
		}
	}
</script>

<style lang="scss">
	.forum-detail {
		box-sizing: border-box;
		padding: 32rpx;
		padding-bottom: 120rpx;
		padding-bottom: calc(120rpx + constant(safe-area-inset-bottom));
		padding-bottom: calc(120rpx + env(safe-area-inset-bottom));
		min-height: 100vh;
		background-color: #f8f8f8;

		.top-box {
			display: flex;

			&:not(:last-child) {
				margin-bottom: 26rpx;
			}

			.user {
				width: 128rpx;
				text-align: center;

				.avatar {
					width: 78rpx;
					height: 78rpx;
					border-radius: 50%;
				}

			}

			.name {
				margin-top: 14rpx;
				color: #666666;
				font-size: 24rpx;
			}

			.content {
				flex: 1;
				margin-left: 20rpx;
				display: flex;
				flex-direction: column;

				.text {
					margin-bottom: 12rpx;
					color: #333333;
					font-size: 28rpx;
				}

				.audio {
					margin-bottom: 12rpx;
					margin-left: 10rpx;
					padding: 0 24rpx;
					border-radius: 4rpx;
					width: 310rpx;
					height: 58rpx;
					background-color: #eeeeee;
					display: flex;
					align-items: center;
					position: relative;

					&::after {
						content: '';
						display: block;
						position: absolute;
						left: -10rpx;
						top: 50%;
						width: 20rpx;
						height: 20rpx;
						background-color: #eeeeee;
						transform: translateY(-50%) rotate(45deg);
					}

					.duration {
						color: #333;
						font-size: 24rpx;
					}
				}

				.bottom {
					margin-top: auto;
					display: flex;
					align-items: center;
					justify-content: space-between;

					.time {
						color: #999999;
						font-size: 22rpx;
					}

					.icon {
						width: 36rpx;
						height: 36rpx;
					}
				}
			}
		}

		.comment-card {
			margin-top: 20rpx;
			padding: 0 28rpx;
			border-radius: 20rpx;
			background-color: #fff;

			.item {
				padding: 28rpx 0;

				&:not(:last-child) {
					border-bottom: 1rpx solid #eee;
				}

				.content {
					display: flex;
				}

				.user {
					width: 128rpx;
					text-align: center;

					.avatar {
						width: 78rpx;
						height: 78rpx;
						border-radius: 50%;
					}

					.name {
						margin-top: 14rpx;
						color: #666666;
						font-size: 24rpx;
					}
				}

				.info {
					flex: 1;
					margin-left: 20rpx;
					display: flex;
					flex-direction: column;

					.comment-text {
						margin-bottom: 12rpx;
						color: #333333;
						font-size: 28rpx;
					}

					.audio {
						margin-bottom: 12rpx;
						margin-left: 10rpx;
						padding: 0 24rpx;
						border-radius: 4rpx;
						width: 310rpx;
						height: 58rpx;
						background-color: #f1f1f1;
						display: flex;
						align-items: center;
						position: relative;

						&::after {
							content: '';
							display: block;
							position: absolute;
							left: -10rpx;
							top: 50%;
							width: 20rpx;
							height: 20rpx;
							background-color: #f1f1f1;
							transform: translateY(-50%) rotate(45deg);
						}

						.duration {
							color: #333;
							font-size: 24rpx;
						}
					}

					.bottom {
						margin-top: auto;
						display: flex;
						align-items: center;
						justify-content: space-between;

						.time {
							color: #999999;
							font-size: 22rpx;
						}

						.icon {
							width: 36rpx;
							height: 36rpx;
						}
					}
				}

				.reply-box {
					margin-top: 20rpx;
					padding: 0 20rpx;
					border-radius: 10rpx;
					background-color: #f8f8f8;

					.reply-item {
						padding: 24rpx 0;
						display: flex;

						.info {
							display: flex;
							flex-direction: column;

							.reply-name {
								margin-bottom: 6rpx;
								color: #999999;
								font-size: 22rpx;
							}

							.comment-text {
								min-height: auto;
								margin-bottom: 12rpx;
							}

							.bottom {
								margin-top: auto;
							}
						}
					}

					.more {
						padding: 10rpx 0 28rpx;
						color: #666;
						font-size: 26rpx;
						text-align: center;
					}
				}
			}
		}

		.wifi-cont {
			width: 26rpx;
			height: 26rpx;
			position: relative;
			transform: rotate(135deg);
			overflow: hidden;

			&.animation {
				.second {
					animation: fade 1s linear .1s infinite;
				}

				.third {
					animation: fade 1s linear .4s infinite;
				}
			}

			.wifi-circle {
				box-sizing: border-box;
				border: 4rpx solid #333;
				border-radius: 50%;
				position: absolute;
			}

			.first {
				width: 0rpx;
				height: 0rpx;
				left: 18rpx;
				top: 18rpx;
			}

			.second {
				width: 20rpx;
				height: 20rpx;
				left: 12rpx;
				top: 12rpx;
			}

			.third {
				width: 30rpx;
				height: 30rpx;
				left: 6rpx;
				top: 6rpx;
			}
		}

		.bottom-box {
			position: fixed;
			bottom: 0;
			left: 0;
			right: 0;
			z-index: 10;
			height: 100rpx;
			padding-right: 12rpx;
			padding-bottom: 0;
			padding-bottom: constant(safe-area-inset-bottom);
			padding-bottom: env(safe-area-inset-bottom);
			background-color: #fff;
			display: flex;
			align-items: center;

			.emoji {
				width: 90rpx;
				height: 100rpx;
				display: flex;
				align-items: center;
				justify-content: center;

				.icon {
					width: 52rpx;
					height: 52rpx;
				}
			}

			.voice {
				flex: 1;
				height: 80rpx;
				line-height: 80rpx;
				text-align: center;
				font-size: 28rpx;
				padding: 0 20rpx;
				border-radius: 12rpx;
				background-color: #f0f0f0;
			}

			.input-box {
				flex: 1;
				display: flex;

				.input {
					flex: 1;
					padding: 0 20rpx;
					border-radius: 12rpx;
					height: 80rpx;
					line-height: 80rpx;
					font-size: 28rpx;
					background-color: #f0f0f0;
				}

				.send {
					margin-left: 10rpx;
					width: 110rpx;
					height: 80rpx;
					border-radius: 12rpx;
					background-color: #0089ff;
					display: flex;
					align-items: center;
					justify-content: center;

					.icon {
						width: 40rpx;
						height: 40rpx;
					}
				}
			}
		}

		@keyframes fade {
			from {
				opacity: 0;
			}

			to {
				opacity: 1;
			}
		}

		.voice-mask {
			position: fixed;
			z-index: 100;
			left: 50%;
			bottom: 40%;
			width: 370rpx;
			height: 370rpx;
			border-radius: 20rpx;
			transform: translateX(-50%);
			background-color: rgba($color: #000, $alpha: 0.5);
			display: flex;
			align-items: center;
			justify-content: center;

			.voice-enter {
				margin-top: 40rpx;
				display: flex;
				flex-direction: column;
				align-items: center;
				justify-content: center;

				.volume {
					margin-left: 4rpx;
					display: flex;
					flex-direction: column;
					justify-content: start;
					gap: 12rpx;

					.volume-1,
					.volume-2,
					.volume-3 {
						height: 12rpx;
						border-radius: 12rpx;
						background-color: #fff;
					}

					.volume-1 {
						width: 40rpx;
					}

					.volume-2 {
						width: 50rpx;
					}

					.volume-3 {
						width: 60rpx;
						animation: visibilityAnimate 1s linear infinite;
					}
				}
			}

			.voice-cancel {
				margin-top: 40rpx;
				display: flex;
				flex-direction: column;
				align-items: center;
				justify-content: center;

				.text {
					background-color: #df4c4c;
				}
			}

			.icon {
				width: 160rpx;
				height: 160rpx;
			}

			.text {
				margin-top: 20rpx;
				width: 240rpx;
				color: #FFFFFF;
				font-size: 28rpx;
				line-height: 60rpx;
				text-align: center;
				border-radius: 8rpx;
			}
		}

		@keyframes visibilityAnimate {
			0% {
				opacity: 0;
			}

			10% {
				opacity: 1;
			}

			100% {
				opacity: 0;
			}
		}
	}
</style>